import requests
from django.shortcuts import render
from django_redis.serializers import json
import json
from rest_framework.views import APIView
from QQLoginTool.QQtool import OAuthQQ
from rest_framework.response import Response
from django.conf import settings
from rest_framework import status
from sinaweibopy import APIClient

from .models import OAuthQQUser, OAuthSinaUser
from rest_framework_jwt.settings import api_settings
from .utils import generate_save_user_openid
from rest_framework.generics import GenericAPIView
from rest_framework.generics import CreateAPIView
from .serializers import QQUserSerializer, OAuthSinaUserSerializer
from carts.utils import merge_cookie_redis_cart
from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer

class OAuthQQLoginView(APIView):
    def get(self,request):

        #1,创建OAuthQQ对象
        auth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,client_secret=settings.QQ_CLIENT_SECRET,redirect_uri=settings.QQ_REDIRECT_URI,state="/")

        #2,获取qq登陆界面
        login_url = auth.get_qq_url()

        #3,返回响应
        return Response({
            "auth_url":login_url
        })


"""
获取openid
请求路径: /oauth/qq/users
请求方式: GET
请求参数: code
返回值:  access_token  |  user_id, username,token


创建qq用户
请求路径: /oauth/qq/users
请求方式: POST
请求参数: password, mobile,sms_code,access_token
返回值: user_id, username,token

"""
class QQUserOpenIdView(GenericAPIView):

    serializer_class = QQUserSerializer

    def get(self,request):
        #1,获取参数code,判断是否存在
        code = request.query_params.get("code")

        if not code:
            return Response({"message":"code丢失"},status=status.HTTP_400_BAD_REQUEST)

        #2,创建oath对象,通过code获取,access_token
        auth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,client_secret=settings.QQ_CLIENT_SECRET,redirect_uri=settings.QQ_REDIRECT_URI,state="/")
        try:
            access_token = auth.get_access_token(code)

            #3,通过access_token获取openid
            openid = auth.get_open_id(access_token)

            #4,通过openid查询oauthqq对象
            try:
                oauth_qq_user = OAuthQQUser.objects.get(openid=openid)
            except OAuthQQUser.DoesNotExist:
                #①, 没有没有美多用户, 也没有OAuthQQUser用户
                #②, 有美多用户, 没有OAuthQQUser用户

                #5,qq用户没有和美多用户绑定过,加密openid,并返回
                access_token_openid = generate_save_user_openid(openid)
                return Response({"access_token":access_token_openid})

        except Exception:
            return Response({"message":"请求qq服务器异常"},status=status.HTTP_400_BAD_REQUEST)

        #6,oauth_qq_user存在,并且绑定过了美多用户
        user = oauth_qq_user.user

        #7,组织数据,拼接token,返回响应
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            "user_id":user.id,
            "username":user.username,
            "token":token
        })

        #合并购物车
        response = merge_cookie_redis_cart(request,user,response)

        return response

    def post(self,request):
        #1,获取数据
        dict_data = request.data

        #2,获取序列化器,校验数据
        serializer = self.get_serializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        #3,数据入库
        oauth_qq = serializer.save()

        #4,组织,数据返回响应
        user = oauth_qq.user
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            "user_id":user.id,
            "username":user.username,
            "token":token
        })

        #合并购物车
        response = merge_cookie_redis_cart(request,user,response)

        return response




#获取微博登陆url页面
class SinaAuthURLView(APIView):
    def get(self, request):
        next = request.query_params.get('next','/')

        login_url = 'https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s' % (settings.WEIBO_APP_KEY, settings.WEIBO_CALLBACK)

        return Response({'login_url':login_url})



class SinaAuthUserView(CreateAPIView):
    serializer_class = OAuthSinaUserSerializer

    def get(self, request):
        # 获取code，判断code是否存在
        # 使用code去Sina获取access——token
        # 使用access_token查询数据库，是否存在sina用户
        # 存在则直接返回jwt，不存在则自己定义access——token，返回access——token

        code = request.query_params.get('code')
        if not code:
            return Response({'message':'code不能为空'})
        url = 'https://api.weibo.com/oauth2/access_token'

        data = {
            'client_id':settings.WEIBO_APP_KEY,
            'client_secret':settings.WEIBO_APP_SECRET,
            'grant_type':'authorization_code',
            'code':code,
            'redirect_uri':settings.WEIBO_CALLBACK
                }

        try:
            response = requests.post(url,data=data)
        except:
            return Response('获取access_token失败')
        print(response.content.decode())
        result = json.loads(response.content.decode())
        #
        # autu = APIClient(app_key=settings.WEIBO_APP_KEY,app_secret=settings.WEIBO_APP_SECRET,redirect_uri=settings.WEIBO_CALLBACK,state="/")
        # access_token = autu.request_access_token(code)
        access_token = result['access_token']
        try:
            access_token = result['access_token']

        except:
            return Response('code失效，无法获取access_token')

        try:
            sina_user = OAuthSinaUser.objects.get(access_token=access_token)
        except:
            serializer = TJWSSerializer(settings.SECRET_KEY, settings.WEIBO_EXPIRES_IN)

            token = serializer.dumps({'access_token': access_token})

            return Response({'access_token': token})

        else:
            user = sina_user.user

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            response = Response({
                'token': token,
                'user_id': user.id,
                'username': user.username
            })

            # 合并cookie中的购物车记录到redis中
            merge_cookie_redis_cart(request, user, response)

            return response




